<?php

namespace maotool\view\component;

use app\admin\model\AuthGroup;
use http\Exception\RuntimeException;
use maotool\log\Console;
use maotool\object\ReflectionUtil;
use maotool\object\StrUtil;
use maotool\script\PhpScriptUtil;
use maotool\src\test\DemoTest;
use maotool\util\ArrayUtil;
use maotool\util\IdUtil;
use maotool\view\html\Document;
use maotool\view\html\Text;

class ComponentLoader
{

    protected $isComponent = false;

    public function loadComponent($content, $params = [])
    {
        $this->isComponent = true;
        $template = new Document();
        $template->loadComponent($content);
        $document = new Document();
        $document->loadComponent($this->handleComponent($template->childNodes, []));
        return $document;
    }

    public function loadRender($content, $params = [])
    {
        $this->isComponent = false;
        $template = new Document();
        $template->loadComponent($content);
        $document = new Document();
        $document->loadComponent($this->handleComponent($template->childNodes, []));

        $scripts = [];
        $scripts[] = "<script>";
        $scripts[] =  "console.group(JSON.parse(atob(\"".base64_encode(json_encode("maotool log server"))."\")))";
        foreach (Console::$lines as $line) {
            $datas = [];
            foreach ($line["datas"] as $data) {
                $datas[] = "JSON.parse(atob(\"".base64_encode(json_encode($data))."\"))";
            }
            $scripts[] = "console.log(".implode(",", $datas).");";
        }
        $scripts[] =  "console.groupEnd(JSON.parse(atob(\"".base64_encode(json_encode("maotool log server"))."\")))";
        $scripts[] = "</script>";
        $document->innerHTML .= $document->innerHTML.implode("\n", $scripts);
        return $document->outerHTML;
    }

    public function handleComponent($nodes, $slots)
    {
        $elements = [];
        foreach ($nodes as $node) {
            if (is_array($node->attributes)) {
                if (in_array("mt:import", array_keys($node->attributes))) {
                    $pattern = '/^(?P<class>[a-zA-Z_\\\\w]+)::(?P<method>[a-zA-Z_\w]+)\((?P<params>.*)\)$/';
                    $importClz = $node->attributes["mt:import"];
                    if (preg_match_all($pattern, $importClz, $matches, PREG_SET_ORDER)) {
                        $class = $matches[0]['class'];
                        $method = $matches[0]['method'];
                        $params = trim($matches[0]['params'], '()');
                        if (ReflectionUtil::isMethodStatic([$class, $method])) {
                            $iDocument = PhpScriptUtil::expression($node->attributes["mt:import"]);
                        } else {
                            $instanceId = IdUtil::simpleUUID();
                            $instance = ReflectionUtil::instance($class);
                            $iDocument = PhpScriptUtil::expression("\$instance_" . $instanceId . "->" . $method . "(" . $params . ")",
                                ["instance_" . $instanceId => $instance]);
                        }
                        $elements[] = $this->handleComponent($iDocument->childNodes, $node->childNodes);
                    } else {
                        throw new RuntimeException("import error");
                    }
                } else if (in_array("mt:slot-name", array_keys($node->attributes))) {
                    if ($this->isComponent) {
                        $elements[] = $node->outerHTML;
                    } else {
                        $isSlot = true;
                        foreach ($slots as $slot) {
                            if (in_array("mt:slot", array_keys($slot->attributes))) {
                                if ($node->attributes["mt:slot-name"] == $slot->attributes["mt:slot"]) {
                                    $attributes = [];
                                    foreach ($slot->attributes as $key => $value) {
                                        if ($key != "mt:slot") {
                                            $attributes[$key] = $value;
                                        }
                                    }
                                    $slot->attributes = $attributes;
                                    $slot->innerHTML = $this->handleComponent($slot->childNodes, $slots);
                                    $elements[] = $slot->outerHTML;
                                    $isSlot = false;
                                }
                            }
                        }
                        if ($isSlot) {
                            $attributes = [];
                            foreach ($node->attributes as $key => $value) {
                                if ($key != "mt:slot") {
                                    $attributes[$key] = $value;
                                }
                            }
                            $node->attributes = $attributes;
                            $node->innerHTML = $this->handleComponent($node->childNodes, $slots);
                            $elements[] = $node->outerHTML;
                        }
                    }
                } else {
                    $node->innerHTML = $this->handleComponent($node->childNodes, $slots);
                    $elements[] = $node->outerHTML;
                }
            } else {
                $node->innerHTML = $this->handleComponent($node->childNodes, $slots);
                $elements[] = $node->outerHTML;
            }
        }
        return implode("", $elements);
    }

}